diff options
author | Tamar Christina <tamar@zhox.com> | 2016-10-31 21:03:14 +0000 |
---|---|---|
committer | Tamar Christina <tamar@zhox.com> | 2016-10-31 21:03:14 +0000 |
commit | 795be0ea60fc81aefdaf6ecb1dc9b03c4a5c9f86 (patch) | |
tree | c1b71a9a55e6395c21308bb243094d5163178281 | |
parent | 80d4a03332e09064e5542924f2897d7eb573f19e (diff) | |
download | haskell-795be0ea60fc81aefdaf6ecb1dc9b03c4a5c9f86.tar.gz |
Align GHCi's library search order more closely with LDs
Summary:
Given a static library and an import library in the same folder. e.g.
```
libfoo.a
libfoo.dll.a
```
running `ghci -lfoo` we should prefer the import library `libfoo.dll.a`
over `libfoo.a` because we prefer having to just load the DLL.
And not having to do any linking.
This also more closely emulated the behaviour of LD, which has a search order of
```
libxxx.dll.a
xxx.dll.a
libxxx.a
cygxxx.dll (*)
libxxx.dll
xxx.dll
```
Test Plan: ./validate
Reviewers: RyanGlScott, austin, hvr, bgamari, erikd, simonmar
Reviewed By: RyanGlScott
Subscribers: thomie, #ghc_windows_task_force
Differential Revision: https://phabricator.haskell.org/D2651
GHC Trac Issues: #12771
-rw-r--r-- | compiler/ghci/Linker.hs | 7 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/Makefile | 10 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/T12771.stdout | 1 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/all.T | 5 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/foo.c | 6 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/foo_dll.c | 4 | ||||
-rw-r--r-- | testsuite/tests/rts/T12771/main.hs | 5 |
7 files changed, 35 insertions, 3 deletions
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs index a2ca1b514b..73d0fac1f5 100644 --- a/compiler/ghci/Linker.hs +++ b/compiler/ghci/Linker.hs @@ -1281,7 +1281,8 @@ loadFrameworks hsc_env platform pkg -- If it isn't present, we assume that addDLL in the RTS can find it, -- which generally means that it should be a dynamic library in the -- standard system search path. - +-- For GHCi we tend to prefer dynamic libraries over static ones as +-- they are easier to load and manage, have less overhead. locateLib :: HscEnv -> Bool -> [FilePath] -> String -> IO LibrarySpec locateLib hsc_env is_hs dirs lib | not is_hs @@ -1290,16 +1291,16 @@ locateLib hsc_env is_hs dirs lib -- then look in library-dirs for a static library (libfoo.a) -- then look in library-dirs and inplace GCC for a dynamic library (libfoo.so) -- then check for system dynamic libraries (e.g. kernel32.dll on windows) - -- then try "gcc --print-file-name" to search gcc's search path -- then try looking for import libraries on Windows (.dll.a, .lib) + -- then try "gcc --print-file-name" to search gcc's search path -- then look in library-dirs and inplace GCC for a static library (libfoo.a) -- for a dynamic library (#5289) -- otherwise, assume loadDLL can find it -- = findDll `orElse` findSysDll `orElse` - tryGcc `orElse` tryImpLib `orElse` + tryGcc `orElse` findArchive `orElse` assumeDll diff --git a/testsuite/tests/rts/T12771/Makefile b/testsuite/tests/rts/T12771/Makefile new file mode 100644 index 0000000000..d6960a022a --- /dev/null +++ b/testsuite/tests/rts/T12771/Makefile @@ -0,0 +1,10 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +T12771: + '$(TEST_CC)' -c foo.c -o foo.o + '$(AR)' rsc libfoo.a foo.o + '$(TEST_HC)' -shared foo_dll.c -o libfoo-1.dll + mv libfoo-1.dll.a libfoo.dll.a + echo main | '$(TEST_HC)' $(TEST_HC_OPTS_INTERACTIVE) main.hs -lfoo -L"$(PWD)" diff --git a/testsuite/tests/rts/T12771/T12771.stdout b/testsuite/tests/rts/T12771/T12771.stdout new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/testsuite/tests/rts/T12771/T12771.stdout @@ -0,0 +1 @@ +1 diff --git a/testsuite/tests/rts/T12771/all.T b/testsuite/tests/rts/T12771/all.T new file mode 100644 index 0000000000..50933d5e67 --- /dev/null +++ b/testsuite/tests/rts/T12771/all.T @@ -0,0 +1,5 @@ +test('T12771', [ extra_clean(['libfoo.a', 'libfoo-1.dll', 'foo.o', 'main.o']) + , extra_files(['foo.c', 'main.hs', 'foo_dll.c']) + , unless(opsys('mingw32'), skip) + ], + run_command, ['$MAKE -s --no-print-directory T12771']) diff --git a/testsuite/tests/rts/T12771/foo.c b/testsuite/tests/rts/T12771/foo.c new file mode 100644 index 0000000000..af8ad9cb50 --- /dev/null +++ b/testsuite/tests/rts/T12771/foo.c @@ -0,0 +1,6 @@ +extern int bar(); + +int foo () +{ + return bar(); +} diff --git a/testsuite/tests/rts/T12771/foo_dll.c b/testsuite/tests/rts/T12771/foo_dll.c new file mode 100644 index 0000000000..8ea6c22735 --- /dev/null +++ b/testsuite/tests/rts/T12771/foo_dll.c @@ -0,0 +1,4 @@ +int foo() +{ + return 1; +} diff --git a/testsuite/tests/rts/T12771/main.hs b/testsuite/tests/rts/T12771/main.hs new file mode 100644 index 0000000000..fbc8f5603c --- /dev/null +++ b/testsuite/tests/rts/T12771/main.hs @@ -0,0 +1,5 @@ +module Main where + +foreign import ccall "foo" c_foo :: Int + +main = print c_foo |